package com.yaDuo.common.request

import android.annotation.SuppressLint
import com.yaDuo.common.util.LogUtil
import okhttp3.OkHttpClient
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

/**
 * @author YaDuo
 * time 2025-01-08 15:19
 * 因为SOB的服务器验证会导致出错
 * 抛出[javax.net.ssl.SSLHandshakeException: Chain validation failed]
 * 用这个绕过验证
 */
class SkipVerificationSSLSocketFactory {

    companion object {
        private const val TAG = "SkipVerificationSSLSocketFactory"
        val instance by lazy { SkipVerificationSSLSocketFactory() }
    }

    /**
     *  创建一个不验证证书链的证书信任管理器
     *  @checkClientTrusted 不进行客户端证书验证
     *  @checkServerTrusted 不进行服务器证书验证
     *  @getAcceptedIssuers 不信任任何证书颁发者
     */
    private val trustAllCerts = arrayOf<TrustManager>(@SuppressLint("CustomX509TrustManager")
    object : X509TrustManager {
        @SuppressLint("TrustAllX509TrustManager")
        override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
        }

        @SuppressLint("TrustAllX509TrustManager")
        override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
        }

        override fun getAcceptedIssuers(): Array<X509Certificate> {
            return arrayOf()
        }
    })

    /**
     *  用[trustAllCerts]创建SSL套接字工厂
     */
    private fun getSSLSocketFactory(): SSLSocketFactory {
        // 安装信任管理器
        val sslContext: SSLContext = SSLContext.getInstance("TLS")
        sslContext.init(null, trustAllCerts, java.security.SecureRandom())
        return sslContext.socketFactory
    }

    /**
     * 获得无需验证任何证书的OkHttpClient实例对象
     */
    fun getOkHttpClientInstance(): OkHttpClient {
        runCatching {
            return OkHttpClient.Builder()
                .sslSocketFactory(getSSLSocketFactory(), trustAllCerts[0] as X509TrustManager)
                .readTimeout(10, TimeUnit.SECONDS)
                .connectTimeout(10, TimeUnit.SECONDS)
                .build()
        }.onFailure {
            LogUtil.e(TAG, it.message!!)
        }
        return OkHttpClient()
    }
}